大家好,鐵人賽堂堂邁入第二十三日!
在過去兩天,我們完成了 iOS App 的架構和網路層。今天,我們終於要開始繪製使用者介面 (UI) 了!一個好的聊天 App,最核心的視覺元素就是「聊天氣泡」。我們將學習如何使用 .xib 檔案,來打造一個可重複使用的、能根據發送者不同而改變樣式的 UITableViewCell。
為了設計一個獨立的、可重複使用的 UI 元件,我們不直接在主畫面上畫,而是使用 .xib (Interface Builder) 檔案。
Cocoa Touch Class 檔案。UITableViewCell。MainTableViewCell。創建完成後,點開 MainTableViewCell.xib,我們將在裡面佈局我們的聊天氣泡。其結構如下:
imgLeft): 一個 UIImageView,用於顯示 Bot 的頭像。imgRight): 另一個 UIImageView,用於顯示使用者的頭像。vView): 一個 UIView,我們會在程式碼中改變它的顏色並加上圓角。lbText): 一個 UILabel,放置在 vView 內部,用於顯示對話內容。
MainTableViewCell.swift)介面畫好了,現在我們需要用程式碼賦予它生命。
@IBOutlet)我們使用 @IBOutlet 將 .xib 中的 UI 元件,與我們的 MainTableViewCell.swift 檔案連接起來。特別重要的是,我們還需要連接控制氣泡左右對齊的「約束 (Constraint)」。
// MainTableViewCell.swift
import UIKit
class MainTableViewCell: UITableViewCell {
    
    @IBOutlet weak var lbText: UILabel!
    @IBOutlet weak var imgRight: UIImageView!
    @IBOutlet weak var imgLeft: UIImageView!
    @IBOutlet weak var vView: UIView!
    
    // 控制氣泡與左側頭像距離的約束
    @IBOutlet weak var bubbleLeadingConstraint: NSLayoutConstraint!
    // 控制氣泡與右側頭像距離的約束
    @IBOutlet weak var bubbleTrailingConstraint: NSLayoutConstraint!
    
    // ...
}
configure 函式這是這個 Cell 的靈魂所在。我們將建立一個 configure 函式,它會接收一筆 Message 資料,然後根據訊息的發送者 (sender) 來動態地改變自己的外觀。
// MainTableViewCell.swift
func configure(with message: Message) {
    lbText.text = message.text
    
    if message.sender == .user {
        // --- 使用者的訊息 ---
        imgLeft.isHidden = true    // 隱藏左側(Bot)頭像
        imgRight.isHidden = false  // 顯示右側(User)頭像
        vView.backgroundColor = .systemBlue
        
        // 關鍵!讓氣泡靠右對齊
        bubbleLeadingConstraint.isActive = false
        bubbleTrailingConstraint.isActive = true
        
    } else { // message.sender == .bot
        // --- Bot 的訊息 ---
        imgLeft.isHidden = false   // 顯示左側(Bot)頭像
        imgRight.isHidden = true   // 隱藏右側(User)頭像
        vView.backgroundColor = UIColor(white: 0.25, alpha: 1.0)
        
        // 關鍵!讓氣泡靠左對齊
        bubbleLeadingConstraint.isActive = true
        bubbleTrailingConstraint.isActive = false
    }
}
佈局的魔法: 氣泡能「靠左」或「靠右」的秘密,就在於我們動態地啟用 (isActive = true) 和禁用 (isActive = false) 了兩個互相衝突的約束。當啟用
bubbleTrailingConstraint時,氣泡就會被「拉」到右邊;反之,啟用bubbleLeadingConstraint時,就會被「拉」到左邊。
今天,我們專注於打造了一個可重複使用的 UI 元件。我們學會了:
.xib 來設計一個自訂的 UITableViewCell。
IBOutlet 連接 UI 元件和約束。
我們的「磚塊」(聊天氣泡)已經準備好了。明天,我們將開始「砌牆」,我們會使用 UITableView,將這些氣泡組合成一個完整的聊天主畫面,並顯示我們的第一段靜態對話!